package fr.resasante.utils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.UUID;

import javax.naming.NamingException;

import org.apache.commons.lang.StringUtils;

import fr.resasante.exception.SystemException;

/**
 * Common usefull methods
 * 
 * @author GEFFROY-DE-VILLEBLAN
 * 
 */
public final class CommonUtils {
	/**
	 * Class instance
	 */
	private static volatile CommonUtils instance = null;

	/**
	 * Constructor
	 * 
	 * @throws NamingException
	 */
	private CommonUtils() {
		super();
	}

	/**
	 * Method returning a Singleton class instance
	 * 
	 * @return Singleton instance
	 * @throws NamingException
	 */
	public final static CommonUtils getInstance() {
		if (CommonUtils.instance == null) {
			synchronized (CommonUtils.class) {
				if (CommonUtils.instance == null) {
					CommonUtils.instance = new CommonUtils();
				}
			}
		}
		return CommonUtils.instance;
	}

	/**
	 * Encrypt a password
	 * 
	 * @param password
	 *            The readable password
	 * @return The encrypted password
	 */
	public String encryptPassword(String password) {
		String encryptedString = "";
		String algo = "";
		try {
			algo = PropertiesUtils.getInstance().getProperty("encryption.algorythm");
			MessageDigest crypt = MessageDigest.getInstance(algo);
			crypt.reset();
			crypt.update(password.getBytes("UTF-8"));
			encryptedString = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			throw new SystemException("No such algorithm : " + algo);
		} catch (UnsupportedEncodingException e) {
			throw new SystemException("Unsupported encoding : UTF-8");
		}
		return encryptedString;
	}

	/**
	 * Generate a salt string
	 * 
	 * @return the salt string
	 */
	public String generateSalt() {
		final UUID id = UUID.randomUUID();
		return id.toString();
	}

	/**
	 * Convert a byte array to Hexadecimal
	 * 
	 * @param hash
	 *            The byte array
	 * @return The Hexadecimal value
	 */
	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

	public String CapitalizeName(String name) {
		String nameCapitalized = name.toLowerCase();
		nameCapitalized = nameCapitalized.replaceAll("  ", " ");
		// For all spaces
		String[] nameParts = nameCapitalized.split(" ");
		nameCapitalized = "";
		for (int i = 0; i < nameParts.length; i++) {
			nameCapitalized += StringUtils.capitalize(nameParts[i]) + " ";
		}
		nameCapitalized = nameCapitalized.trim();
		// For all '
		nameParts = nameCapitalized.split("'");
		nameCapitalized = "";
		for (int i = 0; i < nameParts.length; i++) {
			nameCapitalized += StringUtils.capitalize(nameParts[i]) + "'";
		}
		nameCapitalized = nameCapitalized.replaceAll("'$", "");
		// For all -
		nameParts = nameCapitalized.split("-");
		nameCapitalized = "";
		for (int i = 0; i < nameParts.length; i++) {
			nameCapitalized += StringUtils.capitalize(nameParts[i]) + "-";
		}
		nameCapitalized = nameCapitalized.replaceAll("-$", "");
		return nameCapitalized.trim();
	}

	/**
	 * Creates and returns a {@link java.lang.String} from <code>t</code>’s
	 * stacktrace
	 * 
	 * @param t
	 *            Throwable whose stack trace is required
	 * @return String representing the stack trace of the exception
	 */
	public String getStackTrace(Throwable t) {
		StringWriter stringWritter = new StringWriter();
		PrintWriter printWritter = new PrintWriter(stringWritter, true);
		t.printStackTrace(printWritter);
		printWritter.flush();
		stringWritter.flush();

		return stringWritter.toString();
	}

}